package com.gongj.hystrix.controller;

import com.gongj.commons.pojo.User;
import com.gongj.hystrix.Command.MyHystrixCommand;
import com.gongj.hystrix.Command.UserCollapserCommand;
import com.gongj.hystrix.service.HystrixService;
import com.gongj.hystrix.service.UserService;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@RestController
public class HystrixController {

    @Autowired
    HystrixService hystrixService;

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    UserService userService;

    /**
     * 初步使用
     * @return
     */
    @GetMapping("/getUser")
    public String getUser() {
        return hystrixService.getUser();
    }

    @GetMapping("/getUser2")
    public void getUser2() throws ExecutionException, InterruptedException {
        //同步执行
        // 本例中 commandKey为MyHystrixCommand
        // threadPoolKey为gongj
        // commandGroupKey为gongj
        MyHystrixCommand myHystrixCommand = new MyHystrixCommand(HystrixCommand.Setter.withGroupKey(
                HystrixCommandGroupKey.Factory.asKey("gongj"))
                , restTemplate,"哈哈");
        String execute = (String) myHystrixCommand.execute(); //直接执行
        System.out.println(execute);
        //异步执行
        MyHystrixCommand myHystrixCommand2 = new MyHystrixCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("gongj")), restTemplate,"哈哈哈哈");
        Future queue = myHystrixCommand2.queue();  //先入队，后执行
        //调用get 方法来获取结果
        String o = (String) queue.get();
        System.out.println(o);
    }
    @GetMapping("/getUser3")
    public void getUser3() throws ExecutionException, InterruptedException {
        //异步执行
        Future<String> name2 = hystrixService.getName2();
        //同步执行
        String name = hystrixService.getName();
        System.out.println(name);

        //调用get方法来获取结果
        String o =  name2.get();
        System.out.println(o);
    }
    //通过HystrixThreadPoolKey 来对线程池进行设置
    @GetMapping("/getUser4")
    public String getUser4() throws ExecutionException, InterruptedException {
        MyHystrixCommand myHystrixCommand = new MyHystrixCommand(
                HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("gongj"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("gongjie"))
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("gongjiePoolKey")), restTemplate,"");
        String execute = (String) myHystrixCommand.execute(); //直接执行
        System.out.println(execute);
        MyHystrixCommand myHystrixCommand2 = new MyHystrixCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("gongj")), restTemplate,"");
        Future queue = myHystrixCommand2.queue();  ///先入队，后执行
        String o = (String) queue.get();
        System.out.println(o);
        return execute;
    }


    //继承方式：模拟请求缓存
    @GetMapping("/getUser5")
    public void getUser5() throws ExecutionException, InterruptedException {
        //初始化Hystrix请求上下文
        HystrixRequestContext.initializeContext();
        MyHystrixCommand myHystrixCommand = new MyHystrixCommand(
                HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("gongj"))
                        .andCommandKey(HystrixCommandKey.Factory.asKey("gongjie"))
                        .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("gongjiePoolKey")), restTemplate,"哈哈哈");
       //调用两次 验证缓存是否生效
        MyHystrixCommand myHystrixCommand2 = new MyHystrixCommand(
                HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("gongj"))
                        .andCommandKey(HystrixCommandKey.Factory.asKey("gongjie"))
                        .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("gongjiePoolKey")), restTemplate,"哈哈哈");
        String execute = (String) myHystrixCommand.execute(); //直接执行
        System.out.println(execute);
        String execute2 = (String) myHystrixCommand2.execute(); //直接执行
        System.out.println(execute2);

        Thread.sleep(2000);
        //清除缓存
        MyHystrixCommand.flushCache("哈哈哈");
        //再次进行调用  验证缓存是否被清理
        MyHystrixCommand myHystrixCommand3 = new MyHystrixCommand(
                HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("gongj"))
                        .andCommandKey(HystrixCommandKey.Factory.asKey("gongjie"))
                        .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("gongjiePoolKey")), restTemplate,"哈哈哈");
        String execute3 = (String) myHystrixCommand3.execute(); //直接执行
        System.out.println(execute3);

    }

    @GetMapping("/getUser6")
    public void getUser6() throws ExecutionException, InterruptedException {
        //初始化Hystrix请求上下文
        HystrixRequestContext context = HystrixRequestContext.initializeContext();
        String str = hystrixService.getName6("一万二三四五",5L);
       System.out.println(str);
       //进行睡眠
        Thread.sleep(2000);
        hystrixService.flushCache(5L);
        String str2 = hystrixService.getName6("一万二三四五",5L);
        System.out.println(str2);
    }

    //使用注解测试请求分发
    @GetMapping("/getUserByIds2")
    public void getUserByIds2() throws ExecutionException, InterruptedException {
        HystrixRequestContext ctx = HystrixRequestContext.initializeContext();

        Future<User> users = userService.getUserById("8888");
        Future<User> users3 = userService.getUserById("8888");
        Future<User> users2 = userService.getUserById("999");

        User user = users.get();
        User user2 = users2.get();
        User user3 = users3.get();
        System.out.println(user);
        System.out.println(user2);
        System.out.println(user3);
        Thread.sleep(2000);

        Future<User> users4 = userService.getUserById("1222");
        User user4 = users4.get();
        System.out.println(user4);
        ctx.close();
    }



    //使用继承方式实现请求合并
    @GetMapping("/getUserByIds")
    public void getUserByIds() throws ExecutionException, InterruptedException {
        //初始化上下文
        HystrixRequestContext ctx = HystrixRequestContext.initializeContext();

        UserCollapserCommand userCollapseCommand = new UserCollapserCommand(userService, "9999");

        UserCollapserCommand userCollapseCommand3 = new UserCollapserCommand(userService, "7415852");
        UserCollapserCommand userCollapseCommand2 = new UserCollapserCommand(userService, "9999");
        Future<User> queue = userCollapseCommand.queue();
        Future<User> queue2 = userCollapseCommand2.queue();
        Future<User> queue3 = userCollapseCommand3.queue();
        System.out.println(queue.get());
        System.out.println(queue2.get());
        System.out.println(queue3.get());
        // 进行睡眠
        Thread.sleep(3000);
        UserCollapserCommand userCollapseCommand4 = new UserCollapserCommand(userService, "44444444");
        System.out.println(userCollapseCommand4.queue().get());
        ctx.close();
    }
}
